home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / APLocation / Sources / MacOS_Exceptions.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  12.4 KB  |  485 lines

  1. /*==================================================================
  2.     File:        MacOS_Exceptions.h
  3.     
  4.     Contains:    A collection of routines and macros to handle
  5.                 assertions and exceptions.
  6.  
  7.     Written by:    Sean Parent, modified extensively by Eric Traut
  8.  
  9.     Copyright:
  10.         1989-1993, 1997-1998 by Apple Computer, Inc., all rights reserved.
  11.         Published along with article in the Aug. '92 edition
  12.         of "develop" magazine.
  13. ==================================================================*/
  14.  
  15. /*********************************************************************
  16. MACROS
  17.     EXTERNALS
  18.         check
  19.         check_action
  20.         require
  21.         require_action
  22.         resume
  23.  
  24. *********************************************************************/
  25.  
  26. #ifndef __EXCEPTIONS__
  27. #define __EXCEPTIONS__
  28.  
  29. #ifndef    __MACTYPES__
  30. #include <MacTypes.h>
  31. #endif
  32.  
  33.  
  34. /*********************************************************************
  35.     COMPILER SWITCHES
  36. *********************************************************************/
  37.  
  38. /*
  39.     These defines are used to control the amount of information
  40.     displayed when an assertion fails. DEBUGOFF and WARN will run
  41.     silently. MIN will simply break into the debugger. ON will break
  42.     and display the assertion that failed and the exception (for
  43.     require statements). FULL will also display the source file name
  44.     and line number. They should be set into DEBUGLEVEL. The 
  45.     default LEVEL is OFF.
  46. */
  47.  
  48. #define DEBUGOFF        0
  49. #define DEBUGMIN        1
  50. #define DEBUGON            2
  51. #define DEBUGFULL        3
  52.  
  53. #ifndef    DEBUGLEVEL
  54. #define    DEBUGLEVEL    DEBUGOFF
  55. #endif
  56.  
  57.  
  58. /*********************************************************************
  59.     TYPE DEFINITIONS
  60. *********************************************************************/
  61.  
  62. typedef void (*ExceptionCallBackProc)(const char * inDebugMessage);
  63.  
  64.  
  65. /*********************************************************************
  66.     ROUTINES
  67. *********************************************************************/
  68.  
  69. #ifdef __cplusplus
  70. extern "C" {
  71. #endif
  72.  
  73. StringPtr     AssertionFailed(const char * assertionString);
  74. StringPtr     AssertionFailedFileLine(const char * assertionString, const char * fileString, unsigned int line);
  75. StringPtr     AssertionFailedExceptionRaised(const char * assertionString, const char * exceptionString);
  76. StringPtr     AssertionFailedExceptionRaisedFileLine(const char * assertionString, const char * exceptionString, const char * fileString, unsigned int line);
  77.  
  78. StringPtr     PrintDebugString(const char * debugString);
  79. StringPtr     PrintDebugStringFileLine(const char * debugString, const char * fileString, unsigned int line);
  80.  
  81. void        InstallExceptionCallBack(ExceptionCallBackProc inCallBackProc);
  82.  
  83. #ifdef __cplusplus
  84. }
  85. #endif
  86.  
  87. /*********************************************************************
  88.  
  89. MACRO
  90.     debug_str(string)
  91.  
  92. DESCRIPTION
  93.     If debugging is on then check will print the specified string
  94.     Otherwise it does nothing.
  95.  
  96. *********************************************************************/
  97.  
  98. #if    (DEBUGLEVEL == DEBUGMIN || DEBUGLEVEL == DEBUGON)
  99.  
  100. #define debug_str(string)                                                        \
  101.     DebugStr(AssertionFailed(string));
  102.  
  103. #elif    (DEBUGLEVEL == DEBUGFULL)
  104.  
  105. #define debug_str(string)                                                        \
  106.     DebugStr(AssertionFailedFileLine(string, __FILE__, __LINE__));
  107.     
  108. #else
  109.  
  110. #define debug_str(string)
  111.  
  112. #endif
  113.  
  114. #define debug_is_feature_used() debug_str(gFeatureIsUsed)
  115. #define debug_unexpected_value() debug_str(gUnexpectedValue)
  116. #define debug_unimplemented() debug_str(gUnimplemented)
  117. #define debug_untested() debug_str(gUntested)
  118.  
  119.  
  120. /*********************************************************************
  121.  
  122. MACRO
  123.     debug_stringstream(string)
  124.  
  125. DESCRIPTION
  126.     Just like debug_str() above, but allows use of a string stream.
  127.     
  128.     For example:
  129.     
  130.     #include <sstream>
  131.     debug_stringstream( "I eat " << numFruit << " kumquats daily." )
  132.  
  133. *********************************************************************/
  134.  
  135. #ifdef __cplusplus
  136.  
  137. #if    (DEBUGLEVEL == DEBUGMIN || DEBUGLEVEL == DEBUGON)
  138.  
  139. #define debug_stringstream(sstream)                                    \
  140.     do    {                                                            \
  141.             std::stringstream    debugstring;                        \
  142.             debugstring    << sstream;                                    \
  143.             DebugStr(AssertionFailed((debugstring.str()).c_str()));    \
  144.     } while(0)
  145.  
  146. #elif    (DEBUGLEVEL == DEBUGFULL)
  147.  
  148. #define debug_stringstream(sstream)                                    \
  149.     do    {                                                            \
  150.             std::stringstream    debugstring;                        \
  151.             debugstring    << sstream;                                    \
  152.             DebugStr(AssertionFailedFileLine((debugstring.str()).c_str(), __FILE__, __LINE__));    \
  153.     } while(0)
  154.  
  155. #else
  156.  
  157. #define debug_stringstream(sstream)
  158.  
  159. #endif
  160.  
  161. #endif    // __cplusplus
  162.  
  163. /*********************************************************************
  164.  
  165. MACRO
  166.     check(assertion)
  167.  
  168. DESCRIPTION
  169.     If debugging is on then check will test assertion and if it fails
  170.     break into the debugger. Otherwise check does nothing.
  171.  
  172. *********************************************************************/
  173.  
  174. #if    (DEBUGLEVEL == DEBUGMIN)
  175.  
  176. #define check(assertion)                                                        \
  177.     do {                                                                        \
  178.         if (assertion) {}                                                        \
  179.         else Debugger();                                                        \
  180.     } while (false)
  181.  
  182. #elif    DEBUGLEVEL == DEBUGON
  183.  
  184. #define check(assertion)                                                        \
  185.     do {                                                                        \
  186.         if (assertion) {}                                                        \
  187.         else {                                                                    \
  188.             DebugStr(AssertionFailed(#assertion));                                \
  189.         }                                                                        \
  190.     } while (false)
  191.  
  192. #elif    (DEBUGLEVEL == DEBUGFULL)
  193.  
  194. #define check(assertion)                                                        \
  195.     do {                                                                        \
  196.         if (assertion) {}                                                        \
  197.         else {                                                                    \
  198.             DebugStr(AssertionFailedFileLine(#assertion, __FILE__, __LINE__));    \
  199.         }                                                                        \
  200.     } while (false)
  201.     
  202. #else
  203.  
  204. #define check(assertion)
  205.  
  206. #endif
  207.  
  208. /*********************************************************************
  209.  
  210. MACRO
  211.     check_action(assertion, action)
  212.  
  213. DESCRIPTION
  214.     If debugging is on then check_action will test assertion and if it
  215.     fails break into the debugger then execute action. Otherwise
  216.     check_action does nothing.
  217.     
  218. *********************************************************************/
  219.  
  220. #if    (DEBUGLEVEL == DEBUGMIN)
  221.  
  222. #define check_action(assertion, action)                                            \
  223.     do {                                                                        \
  224.         if (assertion) {}                                                        \
  225.         else {                                                                    \
  226.             Debugger();                                                            \
  227.             { action }                                                            \
  228.     } while (false)
  229.  
  230. #elif    DEBUGLEVEL == DEBUGON
  231.  
  232. #define check_action(assertion, action)                                            \
  233.     do {                                                                        \
  234.         if (assertion) {}                                                        \
  235.         else {                                                                    \
  236.             DebugStr(AssertionFailed(#assertion));                                \
  237.             { action }                                                            \
  238.         }                                                                        \
  239.     } while (false)
  240.  
  241. #elif    (DEBUGLEVEL == DEBUGFULL)
  242.  
  243. #define check_action(assertion, action)                                            \
  244.     do {                                                                        \
  245.         if (assertion) {}                                                        \
  246.         else {                                                                    \
  247.             DebugStr(AssertionFailedFileLine(#assertion, __FILE__, __LINE__));    \
  248.             { action }                                                            \
  249.         }                                                                        \
  250.     } while (false)
  251.  
  252. #else
  253.  
  254. #define check_action(assertion, action)
  255.  
  256. #endif
  257.  
  258. /*********************************************************************
  259.  
  260. MACRO
  261.     require(assertion, exception)
  262.  
  263. DESCRIPTION
  264.     require will test assertion and if it fails:
  265.         break into the debugger if debugging is on.
  266.         goto exception.
  267.  
  268. *********************************************************************/
  269.  
  270. #if    (DEBUGLEVEL == DEBUGMIN)
  271.  
  272. #define require(assertion, exception)                                            \
  273.     do {                                                                        \
  274.         if (assertion) {}                                                        \
  275.         else {                                                                    \
  276.             Debugger();                                                            \
  277.             goto exception;                                                        \
  278.         }                                                                        \
  279.     } while (false)
  280.  
  281. #elif    DEBUGLEVEL == DEBUGON
  282.  
  283. #define require(assertion, exception)                                            \
  284.     do {                                                                        \
  285.         if (assertion) {}                                                        \
  286.         else {                                                                    \
  287.             DebugStr(AssertionFailedExceptionRaised(#assertion, #exception));    \
  288.             goto exception;                                                        \
  289.         }                                                                        \
  290.     } while (false)
  291.  
  292. #elif (DEBUGLEVEL == DEBUGFULL)
  293.  
  294. #define require(assertion, exception)                                            \
  295.     do {                                                                        \
  296.         if (assertion) {}                                                        \
  297.         else {                                                                    \
  298.             DebugStr(AssertionFailedExceptionRaisedFileLine(                    \
  299.                   #assertion, #exception, __FILE__, __LINE__));                    \
  300.             goto exception;                                                        \
  301.         }                                                                        \
  302.     } while (false)
  303.  
  304. #else
  305.  
  306. #define require(assertion, exception)                                            \
  307.     do {                                                                        \
  308.         if (assertion) {}                                                        \
  309.         else {                                                                    \
  310.             goto exception;                                                        \
  311.         }                                                                        \
  312.     } while (false)
  313.  
  314. #endif
  315.  
  316. /*********************************************************************
  317.  
  318. MACRO
  319.     debug_throw(assertion, exception)
  320.  
  321. DESCRIPTION
  322.     debug_throw will test assertion and if it fails:
  323.         break into the debugger if debugging is on.
  324.         throw exception
  325.  
  326. *********************************************************************/
  327.  
  328. #if (DEBUGLEVEL == DEBUGMIN)
  329.  
  330. #define debug_throw(assertion, exception)                                        \
  331.     do {                                                                        \
  332.         if (assertion) {}                                                        \
  333.         else {                                                                    \
  334.             Debugger();                                                            \
  335.             throw exception;                                                    \
  336.         }                                                                        \
  337.     } while (false)                                                                \
  338.  
  339. #elif (DEBUGLEVEL == DEBUGON)
  340.  
  341. #define debug_throw(assertion, exception)                                        \
  342.     do {                                                                        \
  343.         if (assertion) {}                                                        \
  344.         else {                                                                    \
  345.             DebugStr(AssertionFailed(#assertion));                                \
  346.             throw exception;                                                    \
  347.         }                                                                        \
  348.     } while (false)                                                                \
  349.  
  350. #elif (DEBUGLEVEL == DEBUGFULL)
  351.  
  352. #define debug_throw(assertion, exception)                                        \
  353.     do {                                                                        \
  354.         if (assertion) {}                                                        \
  355.         else {                                                                    \
  356.             DebugStr(AssertionFailedFileLine(#assertion, __FILE__, __LINE__));    \
  357.             throw exception;                                                    \
  358.         }                                                                        \
  359.     } while (false)
  360.  
  361. #else
  362.  
  363. #define debug_throw(assertion, exception)                                        \
  364.     do {                                                                        \
  365.         if (assertion) {}                                                        \
  366.         else {                                                                    \
  367.             throw exception;                                                    \
  368.         }                                                                        \
  369.     } while (false)
  370.  
  371. #endif
  372.  
  373. /*********************************************************************
  374.  
  375. MACRO
  376.     forbid(assertion, exception)
  377.  
  378. DESCRIPTION
  379.     require will test assertion and if it passes:
  380.         break into the debugger if debugging is on.
  381.         goto exception.
  382.  
  383. *********************************************************************/
  384.  
  385. #define forbid(bad_assertion, exception)                                        \
  386.     require((!(bad_assertion)), exception)    
  387.  
  388. /*********************************************************************
  389.  
  390. MACRO
  391.     require_action(assertion, exception, action)
  392.  
  393. DESCRIPTION
  394.     require_action will test assertion and if it fails:
  395.         break into the debugger if debugging is on.
  396.         execute action.
  397.         goto exception.
  398.  
  399. *********************************************************************/
  400.  
  401. #if    (DEBUGLEVEL == DEBUGMIN)
  402.  
  403. #define require_action(assertion, exception, action)                            \
  404.     do {                                                                        \
  405.         if (assertion) {}                                                        \
  406.         else {                                                                    \
  407.             Debugger();                                                            \
  408.             { action }                                                            \
  409.             goto exception;                                                        \
  410.         }                                                                        \
  411.     } while (false)
  412.  
  413. #elif    DEBUGLEVEL == DEBUGON
  414.  
  415. #define require_action(assertion, exception, action)                            \
  416.     do {                                                                        \
  417.         if (assertion) {}                                                        \
  418.         else {                                                                    \
  419.             DebugStr(AssertionFailedExceptionRaised(#assertion, #exception));    \
  420.             { action }                                                            \
  421.             goto exception;                                                        \
  422.         }                                                                        \
  423.     } while (false)
  424.  
  425. #elif (DEBUGLEVEL == DEBUGFULL)
  426.  
  427. #define require_action(assertion, exception, action)                            \
  428.     do {                                                                        \
  429.         if (assertion) {}                                                        \
  430.         else {                                                                    \
  431.             DebugStr(AssertionFailedExceptionRaisedFileLine(                    \
  432.                   #assertion, #exception, __FILE__, __LINE__));                    \
  433.             { action }                                                            \
  434.             goto exception;                                                        \
  435.         }                                                                        \
  436.     } while (false)
  437.  
  438. #else
  439.  
  440. #define require_action(assertion, exception, action)                            \
  441.     do {                                                                        \
  442.         if (assertion) {}                                                        \
  443.         else {                                                                    \
  444.             { action }                                                            \
  445.             goto exception;                                                        \
  446.         }                                                                        \
  447.     } while (false)
  448.  
  449. #endif
  450.  
  451. /*********************************************************************
  452.  
  453. MACRO
  454.     forbid_action(assertion, exception, action)
  455.  
  456. DESCRIPTION
  457.     forbid_action will test assertion and if it passes:
  458.         break into the debugger if debugging is on.
  459.         execute action.
  460.         goto exception.
  461.  
  462. *********************************************************************/
  463.  
  464. #define forbid_action(bad_assertion, exception, action)                            \
  465.     require_action((!(bad_assertion)), exception, action)    
  466.  
  467. /********************************************************************/
  468.  
  469.  
  470. /* Exported Globals */
  471. extern const char *    gFeatureIsUsed;
  472. extern const char *    gUnexpectedValue;
  473. extern const char *    gUnimplemented;
  474. extern const char * gUntested;
  475.  
  476.  
  477. #endif        // __EXCEPTIONS__
  478.  
  479.  
  480. /*==================================================================
  481.     Change History (most recent first):
  482.  
  483.     $Log: MacOS_Exceptions.h,v $
  484. ==================================================================*/
  485.